//3.2.1 Initial code 
void LCD_Init(void)
{
    TFT_RESET_LOW;        // RESET low, display off
    HAL_Delay(20);        // delay 20ms
    TFT_RESET_HIGH;       // RESET high, display on
    HAL_Delay(100);       // delay 100ms after RESET is high
    SpiTFT_Command(0x36); // set display orientation
    SpiTFT_Data(0xB4);    // Portrait mode, LCD driver on right
}
#include <stdint.h>
#define LANDSCAPE_IC_UP 0
#define LANDSCAPE_IC_DOWN 1
#define PORTRAIT_IC_UP 2
#define PORTRAIT_IC_DOWN 3
#define COLOR_MODE_RGB444 0
#define COLOR_MODE_RGB565 1
#define LCD_LAST_COLUMN (uint16_t)319 /* 320-1 */
#define LCD_LAST_ROW (uint16_t)239    /* 240-1 */
uint16_t gSpiBuffer[320];
uint8_t gDisplayOrientation;
uint16_t gHostWidth;
uint16_t gHostHeight;
uint16_t gX1;
uint16_t gX2;
uint16_t gY1;
uint16_t gY2;
uint16_t gY;
uint16_t gColor;
uint8_t gVHostStep;
uint32_t gDelayCounter;
uint8_t VHost_Task_RGB565(void);
void VHost_RGB565(void);
void VHost_SendCommand(uint8_t tCommand);
void VHost_SendData(uint8_t tData);
void VHost_SendDataN(uint8_t *pData, uint16_t tNum);
void VHost_SetDisplaySize(uint16_t tWidth, uint16_t tHeight);
void Init_VHost(void);
void VHost_Task(void);
uint8_t VHost_FillRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t tColor);

void VHost_SendCommand(uint8_t tCommand)
{
    LCD_Command(tCommand);
}

void VHost_SendData(uint8_t tData)
{
    LCD_Data(tData);
}

void VHost_SendDataN(uint8_t *pData, uint16_t tNum)
{
    LCD_DataN(pData, tNum);
}

void VHost_SetDisplaySize(uint16_t tWidth, uint16_t tHeight)
{
    gHostWidth = tWidth;
    gHostHeight = tHeight;
}

void Init_VHost(void)
{
    gY = 1;
    gY1 = 0;
    gY2 = 0;
    gVHostStep = 0;
    gDisplayOrientation = LANDSCAPE_IC_UP;
    VHost_SendCommand(0x36);
    VHost_SendData(0xA0);
    VHost_SetDisplaySize(320, 240);
    // VHost_SetDisplaySize(240,320);
    // pFun_Host_Task=VHost_Task_RGB565;
}

void VHost_Task(void)
{
    VHost_RGB565();
    // VHost_RGB444();
}

void VHost_RGB565(void)
{
    switch (gVHostStep)
    {
    case 0:
        if (gDisplayOrientation == LANDSCAPE_IC_DOWN || gDisplayOrientation == LANDSCAPE_IC_UP)
        {
            VHost_SetDisplaySize(320, 240);
            gVHostStep += VHost_FillRect(0, 0, 319, 239, 0xFFFF);
        }
        else
        {
            VHost_SetDisplaySize(240, 320);
            gVHostStep += VHost_FillRect(0, 0, 239, 319, 0xFFFF);
        }
        break;
    case 1:
        if (gDisplayOrientation == LANDSCAPE_IC_DOWN || gDisplayOrientation == LANDSCAPE_IC_UP)
        {
            VHost_SetDisplaySize(320, 240);
            gVHostStep += VHost_FillRect(1, 1, 318, 238, 0);
        }
        else
        {
            VHost_SetDisplaySize(240, 320);
            gVHostStep += VHost_FillRect(1, 1, 238, 318, 0);
        }
        break;
    case 2:
        gVHostStep += VHost_FillRect(10, 10, 50, 50, 0xF800);
        break;
    case 3:
        gVHostStep += VHost_FillRect(11, 51, 80, 90, 0x07E0);
        break;
    case 4:
        gVHostStep += VHost_FillRect(12, 91, 120, 130, 0x001F);
        break;
    case 5:
        gVHostStep += VHost_FillRect(13, 131, 160, 170, 0xFFFF);
        gDelayCounter = 0;
        break;
    // case 6:
    // break;
    case 6:
        gDelayCounter++;
        if (gDelayCounter > 0xFF000)
        {
            VHost_SendCommand(0x36);
            // VHost_SendData(0x00);
            switch (gDisplayOrientation)
            {
            case LANDSCAPE_IC_UP:
                // VHost_SendData(0xA0);
                // gDisplayOrientation=LANDSCAPE_IC_UP;
                VHost_SendData(0x20);
                gDisplayOrientation = LANDSCAPE_IC_DOWN;
                break;
            case LANDSCAPE_IC_DOWN:
                VHost_SendData(0xC0);
                gDisplayOrientation = PORTRAIT_IC_UP;
                break;
            case PORTRAIT_IC_UP:
                VHost_SendData(0x00);
                gDisplayOrientation = PORTRAIT_IC_DOWN;
                break;
            case PORTRAIT_IC_DOWN:
                VHost_SendData(0xA0);
                gDisplayOrientation = LANDSCAPE_IC_UP;
                break;
            }
            gDelayCounter = 0;
            gVHostStep = 0;
        }
        break;
    }
}

uint8_t VHost_FillRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t tColor)
{
    uint8_t tResult;
    if (gY > gY2)
    {
        gX1 = x1;
        gX2 = x2;
        gY1 = y1;
        gY2 = y2;
        if (x2 < x1)
        {
            gX1 = x2;
            gX2 = x1;
        }
        if (y2 < y1)
        {
            gY1 = y2;
            gY2 = y1;
        }
        if (gY2 > gHostHeight - 1)
            gY2 = gHostHeight - 1;
        if (gX2 > gHostWidth - 1)
            gX2 = gHostWidth - 1;
        if (gX1 > gHostWidth - 1)
            gX1 = gHostWidth - 1;
        if (gY1 > gHostHeight - 1)
            gY1 = gHostHeight - 1;
        VHost_SendCommand(0x2A);
        VHost_SendData(gX1 >> 8);
        VHost_SendData(gX1 & 0xFF);
        VHost_SendData(gX2 >> 8);
        VHost_SendData(gX2 & 0xFF);
        VHost_SendCommand(0x2B);
        VHost_SendData(gY1 >> 8);
        VHost_SendData(gY1 & 0xFF);
        VHost_SendData(gY2 >> 8);
        VHost_SendData(gY2 & 0xFF);
        VHost_SendCommand(0x2C);
        gY = gY1;
        gColor = tColor;
        tResult = 0;
    }
    else
        tResult = VHost_Task_RGB565();
    // tResult=(*pFun_Host_Task)();
    return tResult;
}

uint8_t VHost_Task_RGB565(void)
{
    uint16_t x;
    uint8_t tCompleted;
    if (gY <= gY2)
    {
        for (x = 0; x <= gX2 - gX1; x++)
        {
            gSpiBuffer[x] = gColor;
        }
        VHost_SendDataN((uint8_t *)gSpiBuffer, (gX2 - gX1 + 1) * 2);
        gY++;
    }
    if (gY > gY2)
    {
        gY = 0xFFF;
        tCompleted = 1;
    }
    else
    {
        tCompleted = 0;
    }
    return tCompleted;
}